#include "SSD2828.h"
#include "../../DDIC/AllDDIC.h"

void Set_2828_reset(u8 Sig_Mode)
{
    if(Sig_Mode == Mipi_Mode)
    {
        IF_Sel1_Video;
        IF_Sel2_Video;    
    }
    else if(Sig_Mode == CMD_Mode)
    {
        IF_Sel1_Cmd;
        IF_Sel2_Cmd;
    }
    SSD_RESET_LOW;		//复位SSD2828芯片
    delay_ms(200);
    SSD_RESET_HIGH;		
    delay_ms(100); 
}

void SSD2828_W_Cmd(u8 SigMode ,u8 channel,u8 cmd)
{
    if(SigMode == Mipi_Mode)
    {
        SPI_Write_u8_Cmd(SPI3_Mode,channel,cmd);
    }
    else if(SigMode == CMD_Mode)
    {
        MCU_2828_write_CMD(channel,cmd);
    }
}

void SSD2828_W_Cmd_NOCS(u8 cmd)
{
	MCU_2828_write_CMD_NOCS(cmd);
}
    

void SSD2828_W_Data(u8 SigMode ,u8 channel,u16 Value)
{
    if(SigMode == Mipi_Mode)
    {
        SPI_Write_u8_Data(SPI3_Mode,channel,Value);
    }
    else if(SigMode == CMD_Mode)
    {
        MCU_2828_Write_Data(channel,Value);
    }
}

u16 SSD2828_R_Data(u8 SigMode ,u8 channel)
{
    u16  data_code;
    if(SigMode == Mipi_Mode)
    {
        data_code = SPI3_Read_u8_Data(channel);
    }
    else if(SigMode == CMD_Mode)
    {
        data_code = MCU_2828_Read_Data(channel);
    }
    return data_code;
}


void SSD2828_W_Reg(u8 SigMode ,u8 channel,u8 Reg, u16 Value)
{  
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Mipi_Mode)
    {
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
    }
    else if(SigMode == CMD_Mode)
    {
		#ifdef SSD_Command_16	
        SSD2828_W_Data(SigMode ,channel,Value);
		#else
	    SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
	    SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
		#endif
    }
}


u16 SSD2828_R_Reg(u8 SigMode ,u8 channel,u8 Reg)
{
    u16 data;
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Mipi_Mode)
    {
        SSD2828_W_Cmd(SigMode ,channel,0xFA);
        data=(u16)SSD2828_R_Data(SigMode ,channel);
        data= (((u16)SSD2828_R_Data(SigMode ,channel))<<8)|data;
    }

    else if(SigMode == CMD_Mode)
    {    
		#ifdef SSD_Command_16	
        data = SSD2828_R_Data(SigMode ,channel);
		#else
        data=(u16)SSD2828_R_Data(SigMode ,channel);
        data= data|(((u16)SSD2828_R_Data(SigMode ,channel))<<8);
		#endif	
    }
	return data;
}



void SSD2828_W_Array(u8 SigMode ,u8 channel,u8 para[],u8 offerset)
{
	u8 i;
	//zangqiang 201712225
	//代码中断延时函数
	if((para[1+offerset]==0xff)&&(para[2+offerset]==0xff)&&(para[3+offerset]==0xff))
	{
		if((para[4+offerset]>0)&&(para[4+offerset]<=0xff))
		{
			delay_ms(para[4+offerset]);
		}
	}
	else
	{
		SSD2828_W_Reg(SigMode ,channel,0xBC, para[0+offerset]);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Mipi_Mode)
		{    
			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
			for(i = 1; i < para[0+offerset]; i++)
			{
				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
			}
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
			SSD2828_W_Data(SigMode ,channel,(para[2+offerset]<<8)+para[1+offerset]);
			for(i = 0; i < (((para[0+offerset]-2)/2)+((para[0+offerset]-2)%2)); i++)
			{
				SSD2828_W_Data(SigMode ,channel,(para[4+i*2+offerset]<<8)+para[3+i*2+offerset]);
			}
			#else
			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
			for(i = 1; i < para[0+offerset]; i++)
			{
				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
			}
			#endif
		}	
		if((para[0+offerset] == 1)&&(para[1] == 0x11))
			delay_ms(120); 		
	}		
}
void SSD2828_W_RAM_buffer_8bits_part(float pclk,u8 SigMode ,u8* buffer ,u16 length,u8  multiple ,u8 DisMode)
{
  	u32 i;
    u32 Data_Num = 0;
    Data_Num = length*multiple*3;
    if(SigMode == Mipi_Mode)
    {
        if(DisMode == 1) 
        {                        
            while(Data_Num > 0)
            {
                for(i=0;i<length/2;i++)
                {
//                Write_DATA((buffer[i*3+1]<<8) + buffer[i*3]); 	//G1,B1
//          	  Write_DATA((buffer[i*3+(OLED.H_pixel/2)*3]<<8) + buffer[i*3+2]);	//B2,R1
//           	  Write_DATA((buffer[i*3+2+(OLED.H_pixel/2)*3]<<8) + buffer[i*3+1+(OLED.H_pixel/2)*3]); 	//R2,G2
					
//					Write_DATA((buffer[i*3+1]<<14)+ (buffer[i*3]<<12)+ (buffer[i*3]<<2));  // {G3:0,B9:6}{B5:0,XX}
//					Write_DATA((buffer[i*3+2]<<8) + (buffer[i*3+1]>>2));  //{R9:2} {R1:0,G9:4}
//					
//                    Write_DATA((buffer[i*3+1+(OLED.H_pixel/2)*3]<<14)+ (buffer[i*3+(OLED.H_pixel/2)*3]<<12)+ (buffer[i*3+(OLED.H_pixel/2)*3]<<2));  // {G3:0,B9:6}{B5:0,XX}
//					Write_DATA((buffer[i*3+2+(OLED.H_pixel/2)*3]<<8) + (buffer[i*3+1+(OLED.H_pixel/2)*3]>>2));  //{R9:2} {R1:0,G9:4}

				Write_DATA(0X0ff0);  // {G3:0,B9:6}{B5:0,XX}
				Write_DATA(0X0000);  //{R9:2} {R1:0,G9:4}
					
                Write_DATA(0X0000);  // {G3:0,B9:6}{B5:0,XX}
				Write_DATA(0XFF00);  //{R9:2} {R1:0,G9:4}					
					
                    Data_Num-=6;                           
                }                                       
            }
        }
        else if(DisMode == 0)
        {
            for(i = 0;i<(Data_Num/2);i++)
            {
                Write_DATA(buffer[i*2]+(buffer[i*2+1]<<8));
                delay_6ns((pclk < 50) ? 50 : 0);
            } 
        }    
    }
    else if(SigMode == CMD_Mode)
    {
		#ifdef SSD_Command_16
        for(i=0;i<(Data_Num/6);i++)
        {
            Write_DATA((buffer[i*6+1]<<8)+buffer[i*6+2]);//210, 543
            Write_DATA((buffer[i*6+5]<<8)+buffer[i*6]);
            Write_DATA((buffer[i*6+3]<<8)+buffer[i*6+4]);
        }
		#else	
        for(i=0;i<Data_Num/3;i++)
        {
            Write_DATA(buffer[i*3+2]);
            Write_DATA(buffer[i*3+1]);
            Write_DATA(buffer[i*3]);          
        }
		#endif
    }    
}

void SSD2828_W_RAM_Pic(float pclk,u8 SigMode ,u8 channel ,u16 H_Pix,u16 V_Pix,u8 R ,u8 G,u8  B )
{
  	u32 i;
    u16 BC_Data,BD_Data,BE_Data;
    BC_Data = (u16)(H_Pix*V_Pix*3);
    BD_Data = (u16)((H_Pix*V_Pix*3)>>16);
		if(H_Pix*3<=4095)
			BE_Data = (u16)(H_Pix*3);//
		else
			BE_Data = 2048;//			
    
    SSD2828_W_Reg(SigMode ,channel,0xBC,BC_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBD,BD_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBE,BE_Data);                         

    SSD2828_W_Cmd(SigMode ,channel,0xBF);
    SSD2828_W_Cmd(SigMode ,channel,0X2C);   
    SPI_CS_Select(channel,0);
	#ifdef SSD_Command_16
    for(i=0;i<H_Pix*V_Pix/2;i++)
    {
        Write_DATA((G<<8) + R);
        delay_6ns(5);
        Write_DATA((R<<8) + B);
        delay_6ns(5);
        Write_DATA((B<<8) + G);
        delay_6ns(5);
    }
	#else
	for(i=0;i<H_Pix*V_Pix;i++)
	{
        Write_DATA(R);
        Write_DATA(G);
        Write_DATA(B); 
	}
	#endif
    SPI_CS_Select(channel,1);
}

void SSD2828_Set_Window(u8 SigMode ,u8 channel,u16 H_Start,u16 H_End,u16 V_Start,u16 V_End)
{
    u8 Window_Table[2][6];
    
    Window_Table[0][0]=0x05;
    Window_Table[0][1]=0x2A;
    Window_Table[0][2]=H_Start>>8;
    Window_Table[0][3]=H_Start;
    Window_Table[0][4]=(H_End-1)>>8;
    Window_Table[0][5]=(H_End-1);

    Window_Table[1][0]=0x05;
    Window_Table[1][1]=0x2B;
    Window_Table[1][2]=V_Start>>8;
    Window_Table[1][3]=V_Start;
    Window_Table[1][4]=(V_End-1)>>8;
    Window_Table[1][5]=(V_End-1);

    SSD2828_W_Array(SigMode,channel,Window_Table[0],0);
    SSD2828_W_Array(SigMode,channel,Window_Table[1],0);  
}




